
// $Id: PThread.cpp 2 2012-05-22 17:55:16Z gerry@gaboury.biz $

#include "PThread.hpp"
#include <stdexcept>
#include <iostream>
//#include <cmath>

using namespace std;

// Singleton PThread

PThread* PThread::s_instance = 0;

PThread*
PThread::instance()
{
  if ( ! s_instance )
    s_instance = new PThread();
  return s_instance;
}

void
PThread::AddThread ( thread_routine p_tr, void* arg )
{
  int iret;
  // allocate space for thread IDs
  //m_ThreadID.resize(count);

  pthread_t TID;
  if ( ( iret = pthread_create( &TID, NULL, p_tr, arg) ) )
    throw(runtime_error("PThread::AddThread: Error creating thread"));

  m_ThreadID.push_back(TID);
}

void
PThread::AddThreads ( int count, thread_routine p_tr, void* arg )
{
  int iret;
  // allocate space for thread IDs
  //m_ThreadID.resize(count);

  for ( int i = 0; i < count; ++i )
    {
      pthread_t TID;
      if ( ( iret = pthread_create( &TID, NULL, p_tr, arg) ) )
	throw(runtime_error("PThread::AddThread: Error creating thread"));
      m_ThreadID.push_back(TID);
    }
}

// retval should be a pointer to a void* array

void
PThread::join ( void** retval )
{
  int max = count();
  void** ptr = retval;

  for ( int i = 0; i < max; ++i )
    {
      pthread_join( m_ThreadID[i], ptr++ );
      //pthread_join( m_ThreadID[i], (void**)&ptr[i] );
    }
  // clear all thread IDs
  m_ThreadID.clear();
}

// no return value
void
PThread::join ()
{
  int max = count();
  for ( int i = 0; i < max; ++i )
    pthread_join( m_ThreadID[i], NULL );

  // clear all thread IDs
  m_ThreadID.clear();
}
